/**
 * @FileName: ThemeController.java
 * @Author
 * @Description:
 * @Date 2016年1月4日 下午5:53:11
 * @CopyRight ZTE Corporation
 */
package cn.hpclub.server.controller.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.codec.binary.Base64;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Before;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.hpclub.server.bean.SystemConfig;
import cn.hpclub.server.constant.ClientApiConstant;
import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.Blankcard;
import cn.hpclub.server.model.CmccCardOrder;
import cn.hpclub.server.model.CmccOrder;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.model.NetInOrder;
import cn.hpclub.server.model.Notice;
import cn.hpclub.server.model.Themes;
import cn.hpclub.server.model.Token;
import cn.hpclub.server.model.UserFeedback;
import cn.hpclub.server.restful.API;
import cn.hpclub.server.service.OperateDataService;
import cn.hpclub.server.service.PackageService;
import cn.hpclub.server.service.PaymentService;
import cn.hpclub.server.service.SalePromotionService;
import cn.hpclub.server.service.ThemesService;
import cn.hpclub.server.service.TokenService;
import cn.hpclub.server.service.product.ProductService;
import cn.hpclub.server.util.DateKit;
import cn.hpclub.server.util.InterfaceUtil;
import cn.hpclub.server.util.OrderType;
import cn.hpclub.server.util.Params;
import cn.hpclub.server.util.QueryHelper;
import cn.hpclub.server.util.SystemConfigUtil;
import cn.hpclub.server.util.excel.ExcelUtil;

@API("/CmccBussServer/Dzg")
public class DzgController extends BaseClientController<Themes> implements ClientApiConstant{

    private static Logger       log                 = LoggerFactory.getLogger(DzgController.class);
    // 图片地址前缀
    private String              filePathPrefix      = SystemConfigUtil.getSystemConfig().getUploadDir();
    private String              z_img_dir           = "";
    private String              f_img_dir           = "";

    // 客户端传递过来所用到的key
    private static final String PACKAGE_NAME        = "packageName";
    private static final String ADDRESS             = "address";
    private static final String NATION              = "nation";
    private static final String EXPIRE_DATE         = "effectivedate";
    private static final String BIRTHDAY            = "birthday";
    private static final String Z_IMG               = "z_img";
    private static final String VISA_OFFICE         = "visaoffice";
    private static final String PHONE_NUMBER        = "phoneno";
    private static final String TARIFF_CODE         = "business_code";

    private static final String SIM_CARD            = "simcard";
    private static final String HEAD_IMG            = "headimg";
    private static final String PACKAGE_ID          = "packageId";
    private static final String HANDLE_NUMBER       = "handleNo";

    private static final String ORDER_AMOUNT        = "orderamount";
    private static final String NAME                = "name";
    private static final String SEX                 = "sex";
    private static final String F_IMG               = "f_img";
    private static final String ID_CARD             = "idcard";
    public static final String  PAY_PLAT            = "paymentid";

    // 服务器回传所用到的key
    private static final String ORDER_NO            = "OrdeNo";
    private static final String CMCC_ORDER_ID       = "cId";
    private static final String ORDER_AMOUNT_R      = "OrderAmount";
    private static final String PAY_TITLE           = "PayTitle";
    private static final String BACK_URL            = "BackUrl";
    private static final String PAYMENT_ID          = "Paymentid";
    private static final String Z_IMG_R             = "Z_Img";
    public static final String  F_IMG_R             = "F_Img";
    public static final String  PRODUCT_URL         = "ProductUrl";
    private static final String NOTIFY_URL          = "/notifyUrl";

    private static final String BUSINESS_RESULT     = "busi_res";
    private static final String RES_MSG             = "res_msg";

    // 建行支付url
    private static final String CCB_PAY_URL         = "payUrl";
    private static final String PAY_REQUEST_URL     = "/pkgpay";

    private static final int    PAY_ZFB             = 14;
    private static final int    PAY_CCB             = 15;
    private static final int    PAY_CCB_UNION       = 16;

    private final static String ORIGIN_IOS          = "ios";
    private final static String IOS_VERSION_OLD     = "211";
    private final static String ORIGIN              = "origin";
    private final static String VERSION             = "v";

    private final static String ORIGIN_ANDROID      = "1";
    private final static String ANDROID_VERSION_OLD = "211";

    private static final String SERVICE_TYPE        = "service_type";

    /**
     * @Title: QueryDzgModules
     * @Description:客户端restful api demo
     */
    @Before(Tx.class)
    public void QueryDzgModules(){
        String token = getPara(ClientApiConstant.Key.TOKEN);
        Record userInfoRecord = InterfaceUtil.getuserInfoByToken(token);

        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);

        if(userInfoRecord == null){
            JSONObject object = setResponseObj(ClientApiConstant.ResultCode.NOT_EXIST,
                                               ClientApiConstant.Msg.ORG_NOT_EXIST,
                                               ClientApiConstant.Msg.ORG_NOT_EXIST);
            renderText(object.toString());
            return;
        }

        int orgId = userInfoRecord.getInt("org_id");
        int userId = userInfoRecord.getInt("id");
        // log.info("orgId:" + orgId);

        if(orgId <= 0){
            jo = setResponseObj(ClientApiConstant.ResultCode.NOT_EXIST, ClientApiConstant.Msg.ORG_NOT_EXIST,
                                ClientApiConstant.Msg.ORG_NOT_EXIST);
            renderText(jo.toString());
            return;
        }

        JSONArray array = ThemesService.service.getAuthedThemes(orgId, userId);
        jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, array);
        renderText(jo.toString());
    }

    /**
     * 根据店员查询运营数据接口
     */
    @Before(Tx.class)
    public void QueryOperateData(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL, null);
        // log.info("QueryOperateData");
        String dyid = getPara(ClientApiConstant.Key.DYID, null);
        String token = getPara(ClientApiConstant.Key.TOKEN, null);

        try{
            if(StrKit.isBlank(dyid)){
                dyid = String.valueOf(Token.dao.getUserIdByToken(token));
            } else{
                if(isUserValid(dyid, token)){
                    JSONArray array = new JSONArray();

                    array = OperateDataService.service.queryOperateDataById(Integer.parseInt(dyid));

                    jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, array);
                } else{
                    jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.ILLEGAL_USER, null);
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
        }

        // log.info("QueryOperateData:" + jo.toString());
        renderText(jo.toString());
    }

    /**
     * 员工排名接口
     */
    public void GetStoreMasterRankingList(){
        // log.info("QueryOperateData");

        int orgId = TokenService.service.getOrgIdFromToken(getPara(ClientApiConstant.Key.TOKEN));

        JSONArray array = OperateDataService.service.queryRankListByStoreId(orgId);
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, array);
        renderText(jo.toString());
    }

    /**
     * 获取全部成交订单接口
     */
    public void QueryAllOrderData(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL, null);
        // log.info("QueryOperateData");
        String dyid = getPara(ClientApiConstant.Key.DYID, null);
        String token = getPara(ClientApiConstant.Key.TOKEN, null);
        try{
            if(StrKit.isBlank(dyid)){
                dyid = String.valueOf(Token.dao.getUserIdByToken(token));
            } else{
                if(isUserValid(dyid, token)){
                    int type = getParaToInt(ClientApiConstant.Key.TYPE);
                    String starttime = getPara(ClientApiConstant.Key.STARTTIME);
                    String endtime = getPara(ClientApiConstant.Key.ENDTIME);
                    JSONArray array = OperateDataService.service.queryAllOrderData(Integer.parseInt(dyid), type,
                                                                                   starttime, endtime);
                    jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, array);
                } else{
                    jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.ILLEGAL_USER, null);
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
        }

        renderText(jo.toString());
    }

    /**
     * @Title: QueryBaika
     * @Description:获取白卡买断总量以及写卡量,剩余量 void
     */
    public void QueryBaika(){
        try{
            int orgID = getOrgId();
            int total = Blankcard.dao.getTotalSimCardNum(orgID);
            int used = Blankcard.dao.getUsedSimCardCount(orgID);
            // log.info("orgID=" + orgID + ",total=" + total + ",used=" + used);
            responseQueryBaika(1000, "获取白卡数量成功", total, used);
        }
        catch(Exception e){
            log.error(e.getMessage());
            responseQueryBaika(1004, "服务器处理异常", 0, 0);
        }
    }

    private void responseQueryBaika(int resultCode, String message, int total, int used){
        JSONObject jo = new JSONObject().put("ResultCode", resultCode).put("Message", message);
        JSONObject data = new JSONObject().put("TotalCount", total).put("UsedCount", used).put("SurplusCount",
                                                                                               (total - used));
        jo.put("Data", data);
        renderJson(jo.toString());
    }

    /**
     * @Title: CheckBaiKa
     * @Description:检查是否还有白卡接口 void
     */
    public void CheckBaiKa(){
        try{
            int orgID = getOrgId();
            int total = Blankcard.dao.getTotalSimCardNum(orgID);
            int used = Blankcard.dao.getUsedSimCardCount(orgID);
            // log.info("orgID=" + orgID + ",total=" + total + ",used=" + used);
            responseCheckBaika(1000, "", (total > used) ? "" : "剩余白卡数量为0", total > used ? 1 : 0);
        }
        catch(Exception e){
            log.error(e.getMessage());
            responseCheckBaika(1004, "服务器处理异常", "", 0);
        }
    }

    /**
     * @Title: responseCheckBaika
     * @Description:TODO
     * @param resultCode
     *            TODO
     * @param message
     *            TODO
     * @param dataMessage
     *            TODO
     * @param result
     *            TODO
     */

    private void responseCheckBaika(int resultCode, String message, String dataMessage, int result){
        JSONObject jo = new JSONObject().put("ResultCode", resultCode).put("Message", message);
        JSONObject data = new JSONObject().put("Result", result).put("Message", dataMessage);
        jo.put("Data", data);
        renderJson(jo.toString());
    }

    /**
     * @Title: getOrgId
     * @Description:获取机构ID，如果参数中不存在，则从Token中获取
     * @return int
     */

    private int getOrgId(){
        String storeID = getPara("storeID");
        int orgID = 0;
        if(StrKit.isBlank(storeID)){
            orgID = TokenService.service.getOrgIdFromToken(getPara(ClientApiConstant.Key.TOKEN));
        } else{
            orgID = Integer.parseInt(storeID);
        }
        // log.info("orgID=" + orgID);
        return orgID;
    }

    public void ChooseTelphoneNetin(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        String type = getPara(ClientApiConstant.Key.TYPE);
        if(type == null){
            paramError();
            return;
        }
        int intType = Integer.valueOf(type);// 0 表示普号， 1 表示靓号，2 营销活动选号入网
        if((intType != 0) && (intType != 1) && (intType != 2)){
            paramError();
            return;
        }

        int orgId = TokenService.service.getOrgIdFromToken(getPara(ClientApiConstant.Key.TOKEN));

        JSONArray array = PackageService.service.getPackagesByType(intType, orgId);
        jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, array);
        renderText(jo.toString());
    }

    /**
     * @Title: paramError
     * @Description:TODO void
     */
    private void paramError(){
        JSONObject jo = null;
        jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.PARA_ILLEGAL,
                            ClientApiConstant.Msg.PARA_ILLEGAL);
        renderText(jo.toString());
    }

    /**
     * @Title: QueryNewsTitle
     * @Description:获取大掌柜新闻标题列表 void
     */
    public void QueryNewsTitle(){
        JSONObject result = new JSONObject();
        try{
            int orgId = getOrgId();
            String sql = Notice.dao.getNoticeListSqlForClient(orgId);
            List<Notice> list = Notice.dao.find(sql);
            JSONArray data = new JSONArray();
            for(Notice item : list){
                int id = item.getInt("id");
                String title = item.getStr("title");
                data.put(new JSONObject().put("Id", id).put("Title", title));
            }
            result.put("ResultCode", 1000).put("Message", "").put("Data", data);
        }
        catch(Exception e){
            log.error(e.getMessage());
            result = new JSONObject();
            result.put("ResultCode", 1004).put("Message", "服务器处理异常").put("Data", "");
        }
        // log.info("result.toString():" + result.toString());
        renderJson(result.toString());
    }

    /**
     * @Title: QueryMonthIncomeList
     * @Description:历史酬金
     */
    public void QueryMonthIncomeList(){

        renderText(SalePromotionService.service
                .queryMonthIncomeList(Token.dao.getUserIdByToken(getPara(ClientApiConstant.Key.TOKEN)),
                                      getParaToInt(ClientApiConstant.Key.PAGE_INDEX, 1),
                                      getParaToInt(ClientApiConstant.Key.PAGE_SIZE, 10)));
    }

    /**
     * @Title: QueryCurrentMonthIncome
     * @Description:按月份查询酬金接口
     */
    public void QueryCurrentMonthIncome(){
        int userId = Token.dao.getUserIdByToken(getPara(ClientApiConstant.Key.TOKEN));
        String time = getPara(ClientApiConstant.Key.SALE_DATE);
        String history = getPara(ClientApiConstant.Key.IS_HISTORY);
        boolean isHistory = ("1".equals(history)) ? true : false;

        renderText(SalePromotionService.service.queryCurrentMonthIncome(userId, time, isHistory));
    }

    private boolean isIosOlderVersion(String origin, String v){
        log.info("device type:" + origin + ",version:" + v);
        if((origin != null)
                && (ORIGIN_IOS.equalsIgnoreCase(origin) && (v != null) && (v.compareTo(IOS_VERSION_OLD) < 0))){
            log.info("ios older version");
            return true;
        }
        return false;
    }

    private boolean isOlderApkVersion(String origin, String v){
        log.info("device type:" + origin + ",version:" + v);
        if((origin != null)
                && (ORIGIN_ANDROID.equalsIgnoreCase(origin) && (v != null) && (v.compareTo(ANDROID_VERSION_OLD) <= 0))){
            log.info("android older version");
            return true;
        }
        return false;
    }

    /**
     * @Title: AddOrdersCmcc
     * @Description:添加选号入网订单
     */
    @Before(Tx.class)
    public void AddOrdersCmcc(){
        log.info("v1 AddOrdersCmcc is called.");
        String msg = "版本过低，请升级版本";
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "订单提交失败:" + msg, msg);
        renderText(jo.toString());

    }

    /**
     * @Title: addCmccXHRWOrder
     * @Description:提交选号入网订单，本接口将所有参数都进行了加密,最小改动
     */
    @Before(Tx.class)
    public void addCmccXHRWOrder(){
        log.info("v1 addCmccXHRWOrder is called.");
        String msg = "版本过低，请升级版本";
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "订单提交失败:" + msg, msg);
        renderText(jo.toString());

    }

    /**
     * @Title: checkAndGetData
     * @Description:phoneno/handleNo/packageName/packageId/ business_code/
     *                                                      idcard/
     *                                                      name/sex/birthday/
     *                                                      headimg/nation/
     *                                                      address/visaoffice /
     *                                                      effectivedate必填
     * @param r
     * @return boolean
     */
    private boolean parseOrderData(Params params, NetInOrder r) throws Exception{

        // System.out.println("checkAndGetData in");

        // 所办理业务的号码必须有值，且不为空
        String phoneNumber = params.getPara(PHONE_NUMBER);
        String handleNumber = params.getPara(HANDLE_NUMBER);
        if(StrKit.isBlank(phoneNumber) || StrKit.isBlank(handleNumber)){
            log.error("phoneNumber or handleNumber empty");
            return false;
        }

        // 选号入网，所办理业务的SIM卡必须有值，且不为空
        String simCard = params.getPara(SIM_CARD);
        if(StrKit.isBlank(simCard)){
            log.error("simCard empty");
            return false;
        }

        // 选号入网，所选套餐名称，套餐ID和套餐的资费代码，卡必须有值，且不为空
        String packageName = params.getPara(PACKAGE_NAME);
        String packageId = params.getPara(PACKAGE_ID);
        String tariffCode = params.getPara(TARIFF_CODE);
        if(StrKit.isBlank(packageName) || StrKit.isBlank(packageId) || StrKit.isBlank(tariffCode)){
            log.error("params error.1 pkg");
            return false;
        }

        // 身份证信息，所有必填，并且必须有值，值还应该具备一定的规则：
        String idCard = params.getPara(ID_CARD);
        String name = params.getPara(NAME);
        String sex = params.getPara(SEX);
        String birthday = params.getPara(BIRTHDAY);
        String headImg = params.getPara(HEAD_IMG);
        String nation = params.getPara(NATION);
        String address = params.getPara(ADDRESS);
        String visaOffice = params.getPara(VISA_OFFICE);
        String expireDate = params.getPara(EXPIRE_DATE);
        if(StrKit.isBlank(idCard) || StrKit.isBlank(name) || StrKit.isBlank(sex) || StrKit.isBlank(birthday)
                || StrKit.isBlank(nation) || StrKit.isBlank(address) || StrKit.isBlank(visaOffice)
                || StrKit.isBlank(expireDate)){
            // || StrKit.isBlank(headImg)
            log.error("params error.2 identy");
            return false;
        }

        // 生日，支持四种格式:YYYY/MM/DD,YYYY-MM-DD,YYYYMMDD,YYYY年,统一转成yyyy-MM-dd
        // MM月DD日。到期时间支持任文字，主要有20170107和2015年8月至长期这种类型
        try{
            birthday = formatDate(birthday);
        }
        catch(ParseException e){
            log.error("birthday format error1:" + birthday);
            e.printStackTrace();
            birthday = null;
        }

        if(birthday == null){
            log.error("birthday format error2");
            return false;
        }

        // 没发，或者订单价格为空，默认成0
        String orderAmount = params.getPara(ORDER_AMOUNT);
        if(StrKit.isBlank(orderAmount)){
            r.set(NetInOrder.ORDER_AMOUNT, "0");
            r.set(NetInOrder.PAY_STATUS, 2); // 价格没写默认为0的， 默认写成2，已支付
            r.set(NetInOrder.PAY_TIME, new Date());
        } else{
            Double amount = Double.valueOf(orderAmount);
            log.info("pay amount:" + amount);
            if(amount > 0){
                r.set(NetInOrder.PAY_STATUS, 1); // 默认写成1，未支付
            } else{
                r.set(NetInOrder.PAY_STATUS, 2); // 价格为0的，默认写成2，已支付
                r.set(NetInOrder.PAY_TIME, new Date());
            }

            r.set(NetInOrder.ORDER_AMOUNT, orderAmount);
        }

        // 没发，或者支付方式为空，默认成支付宝支付
        String payPlat = params.getPara(PAY_PLAT);
        int paymentId = 0;
        if(StrKit.isBlank(payPlat)){
            r.set(NetInOrder.PAY_PLAT, PAY_ZFB); // 默认支付宝支付
            paymentId = PAY_ZFB;
        } else{
            paymentId = Integer.valueOf(payPlat);
            if((paymentId == PAY_ZFB) || (paymentId == PAY_CCB) || (paymentId == PAY_CCB_UNION)){
                r.set(NetInOrder.PAY_PLAT, paymentId);
            } else{
                log.error("paymentId error:" + paymentId);
                return false;
            }
        }

        String fImg = params.getPara(F_IMG);
        String zImg = params.getPara(Z_IMG);
        Date currDate = new Date();
        r.set(NetInOrder.ADDRESS, address);
        r.set(NetInOrder.BIRTHDAY, birthday);
        r.set(NetInOrder.CREATED_TIME, currDate);
        r.set(NetInOrder.OPERATED_TIME, currDate);
        r.set(NetInOrder.EXPIRE_DATE, expireDate);
        r.set(NetInOrder.F_IMG, fImg);
        r.set(NetInOrder.HANDLE_NUMBER, handleNumber);

        int userId = Token.dao.getUserIdByToken(getPara(ClientApiConstant.Key.TOKEN));
        if(userId == 0){
            // 营业员用户不存在，理论上这种情况是进不来的，会被api接口拦截。但还是判断处理一下。
            log.error("user does not exist");
            return false;
        }
        r.set(NetInOrder.HANDLER_USER_ID, userId);
        r.set(NetInOrder.HEAD_IMG, headImg);
        r.set(NetInOrder.IDCARD, idCard);
        r.set(NetInOrder.NAME, name);
        r.set(NetInOrder.NATION, nation);

        String orderId = generatePackageOrderId(userId, paymentId);
        if(orderId == null){
            // 营业员用户不存在，不生成订单。理论上这种情况是进不来的，会被api接口拦截。但还是判断处理一下。
            log.error("user does not exist and gen orderid error");
            return false;
        }
        r.set(NetInOrder.ORDER_ID, orderId);
        r.set(NetInOrder.PACKAGE_ID, packageId);
        r.set(NetInOrder.PACKAGE_NAME, packageName);

        // r.set(NetInOrder.PAY_TIME, null); //mysql上，默认为null
        r.set(NetInOrder.PHONE_NUMBER, phoneNumber);

        r.set(NetInOrder.SEX, sex);
        r.set(NetInOrder.SIM_CARD, simCard);

        r.set(NetInOrder.TARIFF_CODE, tariffCode);
        r.set(NetInOrder.VISA_OFFICE, visaOffice);

        r.set(NetInOrder.Z_IMG, zImg);

        r.set(NetInOrder.APPID, Constant.APPID);

        // 保存机构ID快照
        int orgId = MemberOrg.dao.getOrgIdById(userId);
        r.set(NetInOrder.HANDLER_ORG_ID, orgId);

        // System.out.println("r" + r.get(NetInOrder.NAME));

        return true;
    }

    private void returnOrder(NetInOrder r){
        // 生成身份证图片二进制码（base64编码）
        // String z_img_base64 = toBase64(z_img_dir);
        // String f_img_base64 = toBase64(f_img_dir);
        // System.out.println("z_img_base64 = " + z_img_base64);
        // System.out.println("f_img_base64 = " + f_img_base64);

        // 删除身份证图片
        // deleteIDCardImages();

        JSONObject order = new JSONObject();
        // System.out.println("return order r" + r.get(NetInOrder.NAME));

        order.put(ORDER_NO, r.getStr(NetInOrder.ORDER_ID));
        order.put(ORDER_AMOUNT_R, Double.valueOf(r.get(NetInOrder.ORDER_AMOUNT)));
        order.put(PAY_TITLE, "大掌柜");
        String notify_url = SystemConfigUtil.getSystemConfig().getHostPrefix() + getRequest().getContextPath()
                + NOTIFY_URL;
        order.put(BACK_URL, notify_url);

        String payUrl = SystemConfigUtil.getSystemConfig().getHostPrefix() + getRequest().getContextPath()
                + PAY_REQUEST_URL;
        order.put(CCB_PAY_URL, payUrl);

        // System.out.println("notify url:" + notify_url);
        order.put(PAYMENT_ID, r.getInt(NetInOrder.PAY_PLAT));
        order.put(Z_IMG_R, "生成图片错误");
        order.put(F_IMG_R, "生成图片错误");
        // order.put(Z_IMG_R, StrKit.isBlank(z_img_base64) ? "生成图片错误" :
        // z_img_base64);
        // order.put(F_IMG_R, StrKit.isBlank(f_img_base64) ? "生成图片错误" :
        // f_img_base64);
        order.put(PRODUCT_URL, "http://yyth5.vpclub.cn/dzg/product/0.html");// 无用的

        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY, order);

        renderText(jo.toString());
    }

    /**
     * @Title: deleteIDCardImages
     * @Description:删除身份证图片 void
     */
    private void deleteIDCardImages(){
        File imageFileDir = new File(filePathPrefix + SystemConfig.UPLOAD_IMAGE_IDCARD_DIR);
        if(deleteDir(imageFileDir)){
            log.info("delete IDCard images success");
        } else{
            log.error("delete IDCard images failure");
        }
    }

    /**
     * 
     * @Title: deleteDir
     * @Description:删除身份证图片
     * @param dir
     * @return boolean
     */
    private boolean deleteDir(File dir){
        if(dir.isDirectory()){
            String[] children = dir.list();// 递归删除目录中的子目录下
            for(int i = 0; i < children.length; i++){
                boolean success = deleteDir(new File(dir, children[i]));
                if(!success){
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    /**
     * @Title: toBase64
     * @Description:身份证图片进行Base64编码
     * @param str
     * @return String
     */
    private String toBase64(String imgFile){
        // String imgFile = filePathPrefix + imgPath;// 待处理的图片
        // System.out.println("imgFile = " + imgFile);
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try{
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
            // 对字节数组Base64编码
            return new String(Base64.encodeBase64(data));// 返回Base64编码过的字节数组字符串
        }
        catch(IOException e){
            e.printStackTrace();
            return "";
        }

    }

    private void addOrder(NetInOrder r){
        // System.out.println("add order r" + r.get(NetInOrder.NAME));
        r.save();
    }

    /**
     * @Title: checkAndGetData
     * @Description:phoneno/handleNo/packageName/packageId/ business_code/
     *                                                      idcard/
     *                                                      name/sex/birthday/
     *                                                      headimg/nation/
     *                                                      address/visaoffice /
     *                                                      effectivedate必填
     * @param r
     * @return boolean
     */
    private boolean checkAndGetData(NetInOrder r) throws Exception{

        // System.out.println("checkAndGetData in");

        // 所办理业务的号码必须有值，且不为空
        String phoneNumber = getPara(PHONE_NUMBER);
        String handleNumber = getPara(HANDLE_NUMBER);
        if(StrKit.isBlank(phoneNumber) || StrKit.isBlank(handleNumber)){
            log.error("phoneNumber or handleNumber empty");
            return false;
        }

        // 选号入网，所办理业务的SIM卡必须有值，且不为空
        String simCard = getPara(SIM_CARD);
        if(StrKit.isBlank(simCard)){
            log.error("simCard empty");
            return false;
        }

        // 选号入网，所选套餐名称，套餐ID和套餐的资费代码，卡必须有值，且不为空
        String packageName = getPara(PACKAGE_NAME);
        String packageId = getPara(PACKAGE_ID);
        String tariffCode = getPara(TARIFF_CODE);
        if(StrKit.isBlank(packageName) || StrKit.isBlank(packageId) || StrKit.isBlank(tariffCode)){
            log.error("params error.1 pkg");
            return false;
        }

        // 身份证信息，所有必填，并且必须有值，值还应该具备一定的规则：
        String idCard = getPara(ID_CARD);
        String name = getPara(NAME);
        String sex = getPara(SEX);
        String birthday = getPara(BIRTHDAY);
        String headImg = getPara(HEAD_IMG);
        String nation = getPara(NATION);
        String address = getPara(ADDRESS);
        String visaOffice = getPara(VISA_OFFICE);
        String expireDate = getPara(EXPIRE_DATE);
        if(StrKit.isBlank(idCard) || StrKit.isBlank(name) || StrKit.isBlank(sex) || StrKit.isBlank(birthday)
                || StrKit.isBlank(nation) || StrKit.isBlank(address) || StrKit.isBlank(visaOffice)
                || StrKit.isBlank(expireDate)){
            // || StrKit.isBlank(headImg)
            log.error("params error.2 identy");
            return false;
        }

        // 生日，支持四种格式:YYYY/MM/DD,YYYY-MM-DD,YYYYMMDD,YYYY年,统一转成yyyy-MM-dd
        // MM月DD日。到期时间支持任文字，主要有20170107和2015年8月至长期这种类型
        try{
            birthday = formatDate(birthday);
        }
        catch(ParseException e){
            log.error("birthday format error1:" + birthday);
            e.printStackTrace();
            birthday = null;
        }

        if(birthday == null){
            log.error("birthday format error2");
            return false;
        }

        // 没发，或者订单价格为空，默认成0
        String orderAmount = getPara(ORDER_AMOUNT);
        if(StrKit.isBlank(orderAmount)){
            r.set(NetInOrder.ORDER_AMOUNT, "0");
            r.set(NetInOrder.PAY_STATUS, 2); // 价格没写默认为0的， 默认写成2，已支付
            r.set(NetInOrder.PAY_TIME, new Date());
        } else{
            Double amount = Double.valueOf(orderAmount);
            log.info("pay amount:" + amount);
            if(amount > 0){
                r.set(NetInOrder.PAY_STATUS, 1); // 默认写成1，未支付
            } else{
                r.set(NetInOrder.PAY_STATUS, 2); // 价格为0的，默认写成2，已支付
                r.set(NetInOrder.PAY_TIME, new Date());
            }

            r.set(NetInOrder.ORDER_AMOUNT, orderAmount);
        }

        // 没发，或者支付方式为空，默认成支付宝支付
        String payPlat = getPara(PAY_PLAT);
        int paymentId = 0;
        if(StrKit.isBlank(payPlat)){
            r.set(NetInOrder.PAY_PLAT, PAY_ZFB); // 默认支付宝支付
            paymentId = PAY_ZFB;
        } else{
            paymentId = Integer.valueOf(payPlat);
            if((paymentId == PAY_ZFB) || (paymentId == PAY_CCB) || (paymentId == PAY_CCB_UNION)){
                r.set(NetInOrder.PAY_PLAT, paymentId);
            } else{
                log.error("paymentId error:" + paymentId);
                return false;
            }
        }

        String fImg = getPara(F_IMG);
        String zImg = getPara(Z_IMG);
        Date currDate = new Date();
        r.set(NetInOrder.ADDRESS, address);
        r.set(NetInOrder.BIRTHDAY, birthday);
        r.set(NetInOrder.CREATED_TIME, currDate);
        r.set(NetInOrder.OPERATED_TIME, currDate);
        r.set(NetInOrder.EXPIRE_DATE, expireDate);
        r.set(NetInOrder.F_IMG, fImg);
        r.set(NetInOrder.HANDLE_NUMBER, handleNumber);

        int userId = Token.dao.getUserIdByToken(getPara(ClientApiConstant.Key.TOKEN));
        if(userId == 0){
            // 营业员用户不存在，理论上这种情况是进不来的，会被api接口拦截。但还是判断处理一下。
            log.error("user does not exist");
            return false;
        }
        r.set(NetInOrder.HANDLER_USER_ID, userId);
        r.set(NetInOrder.HEAD_IMG, headImg);
        r.set(NetInOrder.IDCARD, idCard);
        r.set(NetInOrder.NAME, name);
        r.set(NetInOrder.NATION, nation);

        String orderId = generatePackageOrderId(userId, paymentId);
        if(orderId == null){
            // 营业员用户不存在，不生成订单。理论上这种情况是进不来的，会被api接口拦截。但还是判断处理一下。
            log.error("user does not exist and gen orderid error");
            return false;
        }
        r.set(NetInOrder.ORDER_ID, orderId);
        r.set(NetInOrder.PACKAGE_ID, packageId);
        r.set(NetInOrder.PACKAGE_NAME, packageName);

        // r.set(NetInOrder.PAY_TIME, null); //mysql上，默认为null
        r.set(NetInOrder.PHONE_NUMBER, phoneNumber);

        r.set(NetInOrder.SEX, sex);
        r.set(NetInOrder.SIM_CARD, simCard);

        r.set(NetInOrder.TARIFF_CODE, tariffCode);
        r.set(NetInOrder.VISA_OFFICE, visaOffice);

        r.set(NetInOrder.Z_IMG, zImg);

        r.set(NetInOrder.APPID, Constant.APPID);

        // 保存机构ID快照
        int orgId = MemberOrg.dao.getOrgIdById(userId);
        r.set(NetInOrder.HANDLER_ORG_ID, orgId);

        // System.out.println("r" + r.get(NetInOrder.NAME));

        return true;
    }

    public void syncOrderStatus(){
        String orderId = getPara(ORDER_NO);
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        if(!CmccOrder.dao.exist(orderId)){
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "同步业务办理结果失败", "订单不存在");
            renderText(jo.toString());
            return;
        }
        String cmccOrderId = getPara(CMCC_ORDER_ID);
        if(cmccOrderId == null){
            cmccOrderId = "";
        }

        boolean result = getParaToBoolean(BUSINESS_RESULT);
        String msg = getPara(RES_MSG);
        if(result){
            // 支付宝目前尚未记录移动订单号，也尚未细化订单状态
            CmccOrder.dao.updateOrderStatus(orderId, cmccOrderId, CmccOrder.ORDER_SUC, msg, new Date(), "首次办理成功：支付宝");
        } else{
            CmccOrder.dao.updateOrderStatus(orderId, cmccOrderId, CmccOrder.ORDER_FAILED, msg, new Date(), "");
        }

        jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.EMPTY,
                            ClientApiConstant.Msg.EMPTY);
        renderText(jo.toString());
    }

    /**
     * @Title: getPayList
     * @Description:选号入网获取支付类型列表接口 void
     */
    public void getPayList(){
        int userId = Token.dao.getUserIdByToken(getPara(ClientApiConstant.Key.TOKEN));
        JSONObject result = PaymentService.getInstance().getPaymentList(userId, PaymentService.MODULE_ID_XUAN_HAO);
        renderText(result.toString());
    }

    private String generatePackageOrderId(int userId, int payType){
        String dateStr = DateKit.toStr(new Date(), "yyMMdd");
        // System.out.println("dateStr:" + dateStr);
        MemberOrg memberInfo = MemberOrg.dao.getMemberOrgInfoByUserId(userId);
        String cityCode = null;
        String groupId = null;
        boolean userExist = MemberOrg.dao.exist(userId);
        if((!userExist) || (memberInfo == null)){
            return null;
        } else{
            cityCode = "" + memberInfo.getInt("region_id");
            groupId = MemberOrg.dao.getOrgNumCodebyUserid(userId);
            String prefix = (payType == PAY_ZFB) ? OrderType.CMCCORDER_Z.getName() : OrderType.CMCCORDER.getName();
            return prefix + dateStr + InterfaceUtil.getOrderSeq(OrderType.CMCCORDER) + cityCode + groupId;
        }
    }

    /**
     * @Title: formatDate
     * @Description:将四种写法的日期统一转成YYYY-MM-DD
     * @param dateStr
     * @return
     * @throws ParseException
     *             String
     */
    private String formatDate(String dateStr) throws ParseException{
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd");
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = null;
        if((date = formatToDate(dateStr, sdf1)) != null){
            return formatToString(date);
        }

        if((date = formatToDate(dateStr, sdf2)) != null){
            return formatToString(date);
        }

        if((date = formatToDate(dateStr, sdf3)) != null){
            return formatToString(date);
        }

        dateStr = ExcelUtil.removeSpace(dateStr);
        log.info("birthday space removed src:" + dateStr);
        if((date = formatToDate(dateStr, sdf4)) != null){
            return formatToString(date);
        }

        log.error("incorrent format");
        return null;

    }

    /**
     * @Title: formatTo
     * @Description:TODO
     * @param dateStr
     * @param sdf1
     *            void
     */

    private Date formatToDate(String dateStr, SimpleDateFormat sdf1){
        Date date;
        try{
            date = sdf1.parse(dateStr);
        }
        catch(ParseException e){
            date = null;
        }

        return date;
    }

    /**
     * @Title: format
     * @Description:TODO
     * @param date
     * @return String
     */

    private String formatToString(Date date){
        String dateStr;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        dateStr = format.format(date);
        // System.out.println("date2:" + dateStr);
        return dateStr;
    }

    /**
     * 
     * @Title: GetProductList
     * @Description:分级获取商品列表 void
     */
    public void GetProductList(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            // String token = getPara(ClientApiConstant.Key.TOKEN);
            String groupId = getPara(ClientApiConstant.Key.GROUPID);// 店长/店员渠道编码
            log.info("groupId = " + groupId);
            if(StrKit.isBlank(groupId)){
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.PARA_ILLEGAL,
                                    ClientApiConstant.Msg.EMPTY);
            } else{
                JSONArray pts = new JSONArray();
                ConcurrentHashMap<String, String> searchInfo = getProductListSearchInfo(groupId);
                // 店长推荐（省级）商品
                // QueryHelper helper = ProductService.service
                // .getProductListHelper(searchInfo, false,
                // ClientApiConstant.ProductType.RECOMMEND);
                QueryHelper helper = new ProductService().getProductListHelper(searchInfo, false,
                                                                               ClientApiConstant.ProductType.RECOMMEND);
                JSONObject ptJson = getPtJson(helper, searchInfo, ClientApiConstant.ProductType.RECOMMEND);
                pts.put(ptJson);

                // 热销（地市级）商品
                // helper =
                // ProductService.service.getProductListHelper(searchInfo,
                // false,
                // ClientApiConstant.ProductType.HOST);
                helper = new ProductService().getProductListHelper(searchInfo, false,
                                                                   ClientApiConstant.ProductType.HOST);
                ptJson = getPtJson(helper, searchInfo, ClientApiConstant.ProductType.HOST);
                pts.put(ptJson);

                jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS, pts);
            }
        }
        catch(Exception e){
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
            e.printStackTrace();
        }
        log.debug("to client data = " + jo.toString());
        renderText(jo.toString());
    }

    /**
     * @Title: getPtJson
     * @Description:TODO
     * @param helper
     * @param searchInfo
     * @param recommend
     * @return JSONObject
     */
    private JSONObject getPtJson(QueryHelper helper, ConcurrentHashMap<String, String> searchInfo, int productType){
        System.out.println("**************getPtJson*************productType====" + productType);
        // Page<Record> products =
        // ProductService.service.queryProductList(searchInfo, helper);
        Page<Record> products = new ProductService().queryProductList(searchInfo, helper);

        JSONObject ptJson = new JSONObject(JsonKit.toJson(products));
        JSONObject jsObj = new JSONObject();

        jsObj.put(ClientApiConstant.Key.BASE_URL, SystemConfigUtil.getSystemConfig().getHostPrefix());
        jsObj.put(ClientApiConstant.Key.PRODUCT_TYPE, productType);
        jsObj.put(ClientApiConstant.Key.LIST, ptJson.getJSONArray(ClientApiConstant.Key.LIST));

        return jsObj;
    }

    /**
     * @Title: getGetProductListSearchInfo
     * @Description:TODO
     * @param token
     * @return ConcurrentHashMap<String,String>
     */
    private ConcurrentHashMap<String, String> getProductListSearchInfo(String groupId){
        ConcurrentHashMap<String, String> mapData = new ConcurrentHashMap<String, String>();

        mapData.put(ClientApiConstant.Key.GROUPID, groupId);

        mapData.put(ClientApiConstant.Key.KEYWORDS, "");
        mapData.put(ClientApiConstant.Key.PAGE_INDEX, "1");
        mapData.put(ClientApiConstant.Key.PAGE_SIZE, "6");
        mapData.put(ClientApiConstant.Key.SEQUENCE, ClientApiConstant.SequenceType.DESC);// 排序顺序，默认倒序
        mapData.put(ClientApiConstant.Key.SORT, ClientApiConstant.SortType.DEFAULT);// 排序类型，按默认排序（排序字段+销量）
        mapData.put(ClientApiConstant.Key.FILTER, ClientApiConstant.FilterType.ALL);// 按全部过滤（合约机+裸机）

        return mapData;
    }

    /**
     * 获取全部商品列表
     * 
     * @Title: QueryAllProductList
     * @Description:TODO void
     */
    public void QueryAllProductList(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            String productType = getPara(ClientApiConstant.Key.PRODUCT_TYPE);// 商品类型：1推荐（省级）商品、2热销（地市级）商品
            ConcurrentHashMap<String, String> searchInfo = getQueryAllProductSearchInfo(productType);

            if(StrKit.isBlank(productType) || searchInfo == null){
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.PARA_ILLEGAL,
                                    ClientApiConstant.Msg.EMPTY);
            } else{
                QueryHelper helper = ProductService.service.getProductListHelper(searchInfo, true,
                                                                                 Integer.parseInt(productType));

                Page<Record> products = ProductService.service.queryProductList(searchInfo, helper);

                JSONObject ptJson = new JSONObject(JsonKit.toJson(products));
                ptJson.put(ClientApiConstant.Key.BASE_URL, SystemConfigUtil.getSystemConfig().getHostPrefix());
                ptJson.put(ClientApiConstant.Key.PRODUCT_TYPE, Integer.parseInt(productType));

                jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS, ptJson);

            }
        }
        catch(Exception e){
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
            e.printStackTrace();
        }

        renderText(jo.toString());
    }

    /**
     * @param productType
     * @Title: getQueryAllProductSearchInfo
     * @Description:TODO
     * @return ConcurrentHashMap<String,String>
     */
    private ConcurrentHashMap<String, String> getQueryAllProductSearchInfo(String productType){
        ConcurrentHashMap<String, String> mapData = null;

        try{
            String groupId = getPara(ClientApiConstant.Key.GROUPID);// 店长/店员渠道编码

            if(StrKit.notBlank(groupId)){

                mapData = new ConcurrentHashMap<String, String>();
                mapData.put(ClientApiConstant.Key.GROUPID, groupId);
                mapData.put(ClientApiConstant.Key.PRODUCT_TYPE, productType);

                mapData.put(ClientApiConstant.Key.KEYWORDS, getPara(ClientApiConstant.Key.KEYWORDS, ""));
                mapData.put(ClientApiConstant.Key.PAGE_INDEX,
                            String.valueOf(getParaToInt(ClientApiConstant.Key.PAGE_INDEX, 1)));
                mapData.put(ClientApiConstant.Key.PAGE_SIZE,
                            String.valueOf(getParaToInt(ClientApiConstant.Key.PAGE_SIZE, 10)));
                mapData.put(ClientApiConstant.Key.SEQUENCE,
                            getPara(ClientApiConstant.Key.SEQUENCE, ClientApiConstant.SequenceType.DESC));// 排序顺序，默认倒序
                mapData.put(ClientApiConstant.Key.SORT,
                            getPara(ClientApiConstant.Key.SORT, ClientApiConstant.SortType.DEFAULT));// 默认排序（排序字段+销量）
                mapData.put(ClientApiConstant.Key.FILTER,
                            getPara(ClientApiConstant.Key.FILTER, ClientApiConstant.FilterType.ALL));// 按全部过滤（合约机+裸机）

            } else{
                log.error("*****getQueryAllProductSearchInfo params error!!! :: groupId = " + groupId
                        + ",,,productType = " + productType);
            }
        }
        catch(Exception e){
            log.error("*****getQueryAllProductSearchInfo Exception!!!");
            e.printStackTrace();
        }

        return mapData;
    }

    /**
     * @Title: QueryProductList
     * @Description:终端销售获取商品列表接口 void
     */
    public void QueryProductList(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            String token = getPara(ClientApiConstant.Key.TOKEN);
            if(StrKit.isBlank(token)){
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.INVAILD_TOKEN,
                                    ClientApiConstant.Msg.EMPTY);
            } else{
                ConcurrentHashMap<String, String> searchInfo = getSearchInfo(token);

                QueryHelper helper = ProductService.service.getQueryProductListHelper(searchInfo);

                Page<Record> products = ProductService.service.queryProductList(searchInfo, helper);

                JSONObject ptJson = new JSONObject(JsonKit.toJson(products));
                ptJson.put(ClientApiConstant.Key.BASE_URL, SystemConfigUtil.getSystemConfig().getHostPrefix());

                jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS, ptJson);

            }
        }
        catch(Exception e){
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
            e.printStackTrace();
        }

        renderText(jo.toString());
    }

    /**
     * @param token
     * @Title: getSearchInfo
     * @Description:TODO
     * @return ConcurrentHashMap<String,String>
     */
    private ConcurrentHashMap<String, String> getSearchInfo(String token){
        ConcurrentHashMap<String, String> mapData = new ConcurrentHashMap<String, String>();

        mapData.put(ClientApiConstant.Key.ORGID, String.valueOf(TokenService.service.getOrgIdFromToken(token)));
        mapData.put(ClientApiConstant.Key.KEYWORDS, getPara(ClientApiConstant.Key.KEYWORDS, ""));
        mapData.put(ClientApiConstant.Key.PAGE_INDEX,
                    String.valueOf(getParaToInt(ClientApiConstant.Key.PAGE_INDEX, 1)));
        mapData.put(ClientApiConstant.Key.PAGE_SIZE, String.valueOf(getParaToInt(ClientApiConstant.Key.PAGE_SIZE, 10)));
        mapData.put(ClientApiConstant.Key.SEQUENCE, String.valueOf(getParaToInt(ClientApiConstant.Key.SEQUENCE, 0)));
        mapData.put(ClientApiConstant.Key.SORT, String.valueOf(getParaToInt(ClientApiConstant.Key.SORT, 1)));

        return mapData;

    }

    /**
     * @Title: QueryProductDetail
     * @Description:终端销售获取商品详情接口 void
     */
    public void QueryProductDetail(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            String token = getPara(ClientApiConstant.Key.TOKEN);
            String productId = getPara(ClientApiConstant.Key.PRODUCTID);

            if(StrKit.isBlank(token)){
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.INVAILD_TOKEN,
                                    ClientApiConstant.Msg.EMPTY);
            } else if(StrKit.isBlank(productId)){
                jo = setResponseObj(ClientApiConstant.ResultCode.PARAM_ERROR, ClientApiConstant.Msg.PARA_ILLEGAL,
                                    ClientApiConstant.Msg.EMPTY);
            } else{
                Record product = ProductService.service.getProductByIdClient(Integer.parseInt(productId));
                if(product == null){
                    jo = setResponseObj(ClientApiConstant.ResultCode.NOT_EXIST, ClientApiConstant.Msg.PRODUCT_NOT_EXIST,
                                        ClientApiConstant.Msg.EMPTY);
                } else{
                    JSONObject ptJson = new JSONObject(JsonKit.toJson(product));
                    ptJson.put(ClientApiConstant.Key.BASE_URL, SystemConfigUtil.getSystemConfig().getHostPrefix());

                    jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS,
                                        ptJson);
                }

            }

        }
        catch(Exception e){
            jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, ClientApiConstant.Msg.MSG_EXCEPTION,
                                ClientApiConstant.Msg.EMPTY);
            e.printStackTrace();
        }
        renderText(jo.toString());
    }

    /**
     * @Title: UpdateWriteCardOrder
     * @Description:更新写卡/换卡订单记录 void
     */
    public void UpdateWriteCardOrder(){
        CmccCardOrder model = getModel(CmccCardOrder.class);
        model.set("name", getPara("name"));
        model.set("phone_no", getPara("phone"));
        model.set("emp_code", getPara("empCode"));
        model.set("org_id", getPara("orgId"));
        model.set("business_type", getPara("opType"));
        model.set("card_phone_no", getPara("custPhone"));
        model.set("card_number", getPara("blankcard"));
        model.set("business_name", getPara("businessName"));
        model.set("business_code", getPara("businessCode"));
        model.set("created_time", new Date());
        model.save();
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS,
                                       ClientApiConstant.Msg.EMPTY);
        renderJson(jo.toString());
    }

    public void feedback(){
        String userId = getPara("userId");
        String empCode = getPara("EmpCode");
        String orgId = getPara("storeId");
        String cityCode = getPara("CityCodeId");
        String type = getPara("type");
        String content = getPara("content");
        try{
            checkParams(userId, empCode, orgId, cityCode, type, content);
            Record userInfo = getUserInfo(userId);
            saveFeedback(userId, empCode, orgId, cityCode, type, content, userInfo.getStr("name"),
                         userInfo.getStr("user_name"), getCityName(cityCode));
            JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, ClientApiConstant.Msg.SUCCESS,
                                           ClientApiConstant.Msg.EMPTY);
            renderJson(jo.toString());
        }
        catch(Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.SERVER_EXCEPTION, e.getMessage(),
                                           ClientApiConstant.Msg.EMPTY);
            renderText(jo.toString());
        }
    }

    /**
     * @Title: checkParams
     * @Description:检查客户端输入参数
     * @param userId用户ID
     * @param empCode用户工号
     * @param orgId用户所属机构ID
     * @param cityCode用户所属城市ID
     * @param type反馈类型
     * @param content反馈内容
     * @throws IOException
     *             void
     */
    private void checkParams(String userId, String empCode, String orgId, String cityCode, String type, String content)
            throws IOException{
        if(StrKit.isBlank(userId) || StrKit.isBlank(empCode) || StrKit.isBlank(orgId) || StrKit.isBlank(cityCode)
                || StrKit.isBlank(type) || StrKit.isBlank(content)){
            throw new IOException("参数错误，请检查输入参数");
        }
    }

    /**
     * @Title: getUserInfo
     * @Description:根据用户UserId用户用户信息
     * @param userId用户ID
     * @return
     * @throws IOException
     *             Record
     */
    private Record getUserInfo(String userId) throws IOException{
        Record record = Db.findFirst("SELECT user_name, name FROM member_org WHERE id=?", userId);
        if(record == null){
            throw new IOException("参数错误，userId不存在");
        }
        return record;
    }

    /**
     * @Title: getCityName
     * @Description:根据城市ID获取城市名
     * @param cityCode城市ID
     * @return
     * @throws IOException
     *             String
     */
    private String getCityName(String cityCode) throws IOException{
        Record cityRecord = Db.findFirst("SELECT region_name FROM cmcc_city WHERE region_id=?", cityCode);
        if(cityRecord == null){
            throw new IOException("参数错误，cityCode不存在");
        }

        String cityName = cityRecord.getStr("region_name");
        return cityName;
    }

    /**
     * @Title: saveFeedback
     * @Description:报讯反馈信息
     * @param userId用户ID
     * @param empCode用户工号
     * @param orgId用户所属机构ID
     * @param cityCode用户所在城市
     * @param type反馈类型
     * @param content反馈类容
     * @param name用户姓名
     * @param phone用户电话
     * @param cityName城市名字
     *            void
     */
    private void saveFeedback(String userId, String empCode, String orgId, String cityCode, String type, String content,
            String name, String phone, String cityName){
        UserFeedback model = getModel(UserFeedback.class);

        model.put("user_id", userId);
        model.put("emp_code", empCode);
        model.put("org_id", orgId);
        model.put("name", name);
        model.put("phone", phone);
        model.put("city_code", cityCode);
        model.put("city", cityName);
        model.put("type", type);
        model.put("content", content);
        model.put("time", new Date());
        model.put("state", 0);
        model.save();
    }
}
